
#include "efstream.hpp"
#include "exception.hpp"

#include <sys/stat.h>
#include <cerrno>
#include <fstream>
#include <string>

////////////////////////////////////////////////////////////////////////////////

iefstream::iefstream(const char* filename, std::ios_base::openmode mode)
{
    struct stat file_stat;

    if(stat(filename, &file_stat) == 0)
    {
        if(S_IFDIR & (file_stat.st_mode))
        {
            errno = EISDIR;
        }
        else
        {
            open(filename, mode);

            if(!fail())
            {
                return;
            }
        }
    }

    switch(errno)
    {
    case ENOENT:
        throw exception_file_not_found();

    case EACCES:
        throw exception_access_violation();

    default:
        throw exception_unknown();
    }
}

////////////////////////////////////////////////////////////////////////////////

oefstream::oefstream(const char* filename, std::ios_base::openmode mode)
    : filename(filename)
{
    struct stat file_stat;

    if(stat(filename, &file_stat) == 0)
    {
        errno = EEXIST;
    }
    else if(errno == ENOENT)
    {
        open(filename, mode);

        if(!fail())
        {
            return;
        }
    }

    switch(errno)
    {
    case EEXIST:
        throw exception_file_exists();

    case EACCES:
        throw exception_access_violation();

    default:
        throw exception_unknown();
    }
}

oefstream::~oefstream()
{
    if(is_open())
    {
        close();
        std::remove(filename.c_str());
    }
}

////////////////////////////////////////////////////////////////////////////////
